package com.tfjybj.itoo.exam.ext.service;

import com.tfjybj.itoo.exam.entity.OptionEntity;
import com.tfjybj.itoo.exam.ext.mongo.Option;
import com.tfjybj.itoo.exam.ext.mongo.Question;
import com.tfjybj.itoo.exam.model.QuestionMainModel;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.util.*;
import java.util.stream.Collectors;

/**
 * @author 商俊帅
 * @date 2022/01/14 16:00
 **/
@Service("068bb7f1-e649-4efc-9584-02ce3fe870a8")
@Slf4j
public class QuestionService {

    @Autowired
    private MongoTemplate mongoTemplate;

    public List<QuestionMainModel> getQuestionMainModelFromMongo(String courseId, String operator){
        log.info("enter question from mongo courseId:{},operator:{}",courseId,operator);
        long startTime = System.currentTimeMillis();
        List<QuestionMainModel> examQuestionMainModelList = new ArrayList<>();
        Criteria criteria = Criteria.where("courseId").is(courseId)
                .and("operator").is(operator)
                .and("isDelete").is(0)
                .and("isEffective").is(0);
        Query query = new Query(criteria);
        query.limit(10000);
        List<Question> questions = mongoTemplate.find(query, Question.class);

        log.info("question from mongodb real time:{}",System.currentTimeMillis()-startTime);
        if (CollectionUtils.isEmpty(questions)){
            return Collections.EMPTY_LIST;
        }
        questions.stream().forEach(e->{
            QuestionMainModel model = new QuestionMainModel();
            e.toQuestionModel(model);
            List<Option> options = e.getOptions();
            if (!CollectionUtils.isEmpty(options)){
                List<OptionEntity> optionEntities = new ArrayList<>();
                options.stream().forEach(option->{
                    OptionEntity optionEntity = new OptionEntity();
                    option.toOptionEntity(optionEntity);
                    optionEntities.add(optionEntity);
                });
                model.setQuestionSubEntityList(optionEntities);
            }
            examQuestionMainModelList.add(model);
        });
        log.info("question from mongodb convert arribute time:{}",System.currentTimeMillis()-startTime);

        Map<String, List<QuestionMainModel>> childMainModel = examQuestionMainModelList.stream().filter(e -> Objects.nonNull(e.getParentId()))
                .collect(Collectors.groupingBy(QuestionMainModel::getParentId));
        List<QuestionMainModel> parentQuestionList = examQuestionMainModelList.stream().filter(e -> Objects.isNull(e.getParentId()))
                .peek(e->{
                    if (childMainModel.containsKey(e.getId())){
                        e.setQuestionMainModelList(childMainModel.get(e.getId()));
                    }
                }).collect(Collectors.toList());

        log.info("question from mongodb time:{}",System.currentTimeMillis()-startTime);
        return parentQuestionList;
    }
}
